#pragma once

#include <string>
#include <functional>
#include <vector>
#include <unordered_map>
#include <memory>
#include <cstdint>
#include <type_traits>
#include "viml/value_fwd.h"
#include "viml/types.h"
#include "viml/function.h"

namespace viml {

/**
 * 64位NaN-boxing值表示
 * 
 * 使用IEEE 754双精度浮点数的NaN空间来存储非数字类型：
 * - 如果是有效的double且标记为FLOAT，直接存储
 * - 如果是NUMBER（整数），使用NaN空间存储
 * - 如果是其他类型，使用NaN的payload部分存储类型标记和数据
 * 
 * NaN格式：[sign=0][exp=0x7FF][quiet=1][payload=51bits]
 * 我们使用payload的高8位作为类型标记，低43位存储数据
 */
class Value {
private:
    union {
        double number;
        uint64_t bits;
    };

public:
    // NaN-boxing相关常量
    static constexpr uint64_t QNAN_MASK = 0x7FF0000000000000ULL;  // 修改为避免与类型标记冲突
    static constexpr uint64_t TYPE_MASK = 0x000F000000000000ULL;  // 修改为捕获4位以支持BUILTIN类型
    static constexpr uint64_t DATA_MASK = 0x0000FFFFFFFFFFFFULL;
    static constexpr int TYPE_SHIFT = 48;

    // 类型标记
    static constexpr uint64_t TAG_NIL = 1ULL << TYPE_SHIFT;
    static constexpr uint64_t TAG_NUMBER = 2ULL << TYPE_SHIFT;
    static constexpr uint64_t TAG_BOOLEAN = 3ULL << TYPE_SHIFT;
    static constexpr uint64_t TAG_STRING = 4ULL << TYPE_SHIFT;
    static constexpr uint64_t TAG_LIST = 5ULL << TYPE_SHIFT;
    static constexpr uint64_t TAG_DICT = 6ULL << TYPE_SHIFT;
    static constexpr uint64_t TAG_FUNCTION = 7ULL << TYPE_SHIFT;
    static constexpr uint64_t TAG_CLOSURE = 8ULL << TYPE_SHIFT;
    static constexpr uint64_t TAG_BUILTIN = 9ULL << TYPE_SHIFT;
    static constexpr uint64_t TAG_NONE = 10ULL << TYPE_SHIFT;

public:
    // 构造函数
    Value() : bits(QNAN_MASK | TAG_NIL) {}
    Value(int64_t n) : bits(QNAN_MASK | TAG_NUMBER | (static_cast<uint64_t>(n) & DATA_MASK)) {}
    Value(double f) : number(f) {}  // FLOAT类型直接存储为double
    Value(bool b) : bits(QNAN_MASK | TAG_BOOLEAN | (b ? 1 : 0)) {}
    Value(const std::string& s);
    Value(const char* s);
    
    // 静态创建方法
    static Value nil() { return Value(); }
    static Value none() { Value v; v.bits = QNAN_MASK | TAG_NONE; return v; }
    static Value make_number(int64_t n) { return Value(n); }
    static Value make_float(double f) { return Value(f); }
    static Value boolean(bool b) { return Value(b); }
    static Value string(const std::string& s) { return Value(s); }
    static Value list();
    static Value dict();
    static Value function(std::shared_ptr<Function> func);
    static Value closure(std::shared_ptr<Closure> closure);
    static Value builtin_function(const std::string& name, std::function<Value(const std::vector<Value>&)> func);

    // 类型检查
    ValueType type() const;
    bool is_nil() const;
    bool is_none() const;
    bool is_number() const;
    bool is_float() const;
    bool is_string() const;
    bool is_boolean() const;
    bool is_list() const;
    bool is_dict() const;
    bool is_function() const;
    bool is_closure() const;
    bool is_builtin() const;

    // 值提取
    int64_t as_number() const;
    double as_float() const;
    bool as_boolean() const;
    std::string as_string() const;
    std::vector<Value>& as_list() const;
    std::unordered_map<std::string, Value>& as_dict() const;
    std::shared_ptr<Function> as_function() const;
    std::shared_ptr<Closure> as_closure() const;
    const std::function<Value(const std::vector<Value>&)>& as_builtin() const;

    // VimL真值语义
    bool is_truthy() const;

    // 类型转换
    std::string to_string() const;
    int64_t to_number() const;
    double to_float() const;

    // 比较操作
    bool operator==(const Value& other) const;
    bool operator!=(const Value& other) const;
    bool operator<(const Value& other) const;
    bool operator<=(const Value& other) const;
    bool operator>(const Value& other) const;
    bool operator>=(const Value& other) const;

    // 算术操作
    Value operator+(const Value& other) const;
    Value operator-(const Value& other) const;
    Value operator*(const Value& other) const;
    Value operator/(const Value& other) const;
    Value operator%(const Value& other) const;
    Value operator-() const;

    // 逻辑操作
    Value operator&&(const Value& other) const;
    Value operator||(const Value& other) const;
    Value operator!() const;

    // 索引操作
    Value operator[](const Value& key) const;
    Value& operator[](const Value& key);

    // 调试输出
    std::string debug_string() const;
    
    // 调试辅助方法（仅用于测试）
    uint64_t raw_bits() const { return bits; }
    bool is_nan_debug() const { return is_nan(); }
    uint64_t get_tag_debug() const { return get_tag(); }
    uint64_t get_data_debug() const { return get_data(); }

private:
    // 内部辅助方法
    bool is_nan() const;
    uint64_t get_tag() const;
    uint64_t get_data() const;
    Object* get_object() const;
    void set_object(Object* obj);
};

} // namespace viml


